-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add px guide #1156
Add px guide #1156
Conversation
3682c73
to
d6e9c49
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of great work here, thank you!
Left you a few nits and other items for the future.
const url = process.argv[2]; | ||
|
||
(async () => { | ||
const result = await new PageExperienceGuide().analyze(url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't wait for top level await!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes...
const parseFontfaces = require('./helpers/parseFontface'); | ||
|
||
// Pixel 5 XL | ||
const DEFAULT_VIEWPORT = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Is there a URL you could link to that lists dimensions for popular devices?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, do we need to provide a dpi value to puppeteer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Afaik no DPI value needed as the default is 1. Not sure why a link would be helpful here.
* Renders a page in Puppeteer and collects all data required for the page experience recommendations. | ||
*/ | ||
class PageAnalyzer { | ||
constructor(config = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Does the config
parameter need types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added type info
return await this.gatherPageData(page, remoteStyles); | ||
} | ||
|
||
async gatherPageData(page, remoteStyles) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Do these params and the return need to be typed?
* @return {Array<string>} a list of URLs | ||
*/ | ||
const collectFontPreloads = () => { | ||
return Array.from(document.querySelectorAll('link[rel=preload][as=font]')).map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a separate check for invalid preloads somewhere? Perhaps a preload of a value used in a font-face declaration but not preloaded as a font?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet, created an issue.
!request.url().startsWith('https://cdn.ampproject.org') | ||
) { | ||
// Only donwload AMP runtime scripts as they're need for layouting the page | ||
// Once self-hosting is a thing we'll have to change this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a flag for when the CLI tools know self-hosting is valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet, will add later
* @private | ||
*/ | ||
async loadChecks() { | ||
const jsFileExtension = '.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work with the recently launched module mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loads files from the filesystem which we control.
} | ||
`; | ||
parseFontface(styles, 'http://example.com'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For completeness should there be a check with subset fonts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
const fontfaceSrcParser = require('css-font-face-src'); | ||
|
||
/** | ||
* Extracts the best fontface URL for preloading (woff2 > woff > ?). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smart here: I was naively thinking the result would always be woff2
but this code correctly validates if there are other formats available to use.
@@ -0,0 +1,39 @@ | |||
/** | |||
* Copyright 2019 The AMP HTML Authors. All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2021?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the file as no longer needed
* Fixed JSDocs * More tests
d6e9c49
to
6ba0f47
Compare
packages/page-experience/README.md
Outdated
const pageExperienceGuide = new PageExperienceGuide(); | ||
const result = pageExperienceGuide.analyze('https://amp.dev'); | ||
console.log('result') | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason this is wrapped in ()
but not invoked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not at all...fixed
*/ | ||
async execute(url) { | ||
if (!this.started) { | ||
throw new Error('Puppeteer not running, please call `start` first.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any reason you don't just call start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, but somehow I preferred the more explicit symmetry of calling start and shutdown. It's an internal API though so I don't really care...
) { | ||
// Only donwload AMP runtime scripts as they're need for layouting the page | ||
// Once self-hosting is a thing we'll have to change this | ||
// TODO: investigate whether we could cache these locally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could catch them https://theheadless.dev/posts/request-interception/
, and reply with local filesystem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that was my idea as well
return request.continue(); | ||
}); | ||
|
||
// Collect external stylesheets from requests as we can't read them otherwise due to CORS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to miss some stuff as a result of this? Any reason not to just disable CORS in rendering options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That didn't work for me.
} | ||
if (!pageData.fontPreloads.includes(fontface.mainSrc)) { | ||
if (fontface.mainSrc.startsWith('https://fonts.gstatic.com')) { | ||
result.warn({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense to extract these text blobs into an external file?
|
||
if (!fontface.fontDisplay) { | ||
result.warn({ | ||
title: 'Improve LCP using `font-display: optional`', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to extract the warnings into an external file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For translation?
comments and nits, nothing blocking a LGTM though |
ae1425c
to
4a34bb5
Compare
Thanks for the reviews! |
No description provided.